﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Net.Sockets;
using System.Net.Security;
using System.IO;
using System.Security.Authentication;
using System.Web;

namespace ListItTaxi.Web
{
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class AjaxPhoneService
    {

        ListItEntities _ListItEntities = new ListItEntities();

        public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return false;
        }

        private byte[] StringToBytes(string strInput)
        {
            // Assume string is in this format "######## ######## ######## ######## ######## ######## ######## ########"
            System.Diagnostics.Debug.Assert(((strInput.Length + 1) % 9) == 0);

            int groupCount = (strInput.Length + 1) / 9;
            int byteCount = groupCount * 4;

            byte[] bytes = new byte[byteCount];
            for (int i = 0; i < byteCount; i++)
            {
                int offset = i * 2 + (i / 4);
                bytes[i] = Convert.ToByte(strInput.Substring(offset, 2), 16);
            }
            return bytes;
        }

        public bool PushJob(ActiveJob job) 
        {
            string certificatePath = HttpRuntime.AppDomainAppPath + @"Certificate\apn_developer_identity.P12";
            string certificatePassword = "3425batibot";

            try
            {
                X509Certificate2 clientCertificate = new X509Certificate2(certificatePath, certificatePassword);
                iPhoneAPNS apns = new iPhoneAPNS(clientCertificate);
                // apns.PushBadgeNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "), 14);
                // apns.PushMessageNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "), "Alis na ko beh.");
                //apns.PushAudioNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "), "glass.caf");

                var result = from taxi in _ListItEntities.Taxis
                             where taxi.LicenseNo == job.LicenseNo
                             select taxi;

                var taxis = result.ToList<Taxi>();

                foreach (var taxi in taxis)
                {
                    apns.PushCombinedNotification(StringToBytes(taxi.DeviceID), "You have a job request!", null, "default");
                    break;
                }

                return true;
            }
            catch (Exception e)
            {
                job.Accepted = false;
               return false;
            }
        }

        // To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
        // To create an operation that returns XML,
        //     add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
        //     and include the following line in the operation body:
        //         WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";

        #region test services
        [OperationContract]
        [WebGet()]
        public string DoWork()
        {
            /*var result = from taxi in _ListItEntities.Taxis
                         select taxi;

            string s = "";
            foreach (Taxi taxi in result)
                s += taxi.LicenseNo + ',';
            return s;*/

            return "Holly Kamote";
        }
        #endregion

        #region taxi driver specific services
        [OperationContract]
        [WebGet()]
        public string GetJob(string licenceNo)
        {
            var result = from activeJob in _ListItEntities.ActiveJobs
                         where activeJob.LicenseNo == licenceNo
                         select activeJob;
            string s = "";

            foreach (var job in result)
            {
                s = string.Format("{0},{1},{2},{3}", job.CustomerName, job.PickupAddress, job.DestinationAddress, job.MobileNo);

                job.Accepted = true;
                _ListItEntities.SaveChanges();
                break;
            }
            return s;
        }

        [OperationContract]
        [WebGet()]
        public string SetAvailability(string dutyKey, bool available)
        {
            if (available)
                return "Available";
            else
                return "Busy";
        }

        [OperationContract]
        [WebGet()]
        public string ConnectToAPNS()
        {
            string certificatePath = HttpRuntime.AppDomainAppPath + @"Certificate\apn_developer_identity.P12";
            string certificatePassword = "3425batibot";
            try
            {
                X509Certificate2 clientCertificate = new X509Certificate2(certificatePath, certificatePassword);
                iPhoneAPNS apns = new iPhoneAPNS(clientCertificate);
                // apns.PushBadgeNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "), 14);
                // apns.PushMessageNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "), "Alis na ko beh.");
                //apns.PushAudioNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "), "glass.caf");
                apns.PushCombinedNotification(StringToBytes("b76acc7c 9a6dcea6 96312342 0a981a42 cb1975a2 d914b78e 09ef6ff1 ee87ec84 "),
                    "You have a job request!", null, "default");
            }
            catch (Exception e)
            {
                return e.InnerException.Message;
            }
            return certificatePath;
        }

        [OperationContract]
        [WebGet()]
        /// <summary>
        /// Called when a taxi driver is signing on for duty
        /// </summary>
        public bool SignIn()
        {
            return true;
        }

        [OperationContract]
        [WebGet()]
        /// <summary>
        /// Called when a taxi driver is signing off for duty
        /// </summary>
        public bool SignOff()
        {
            return true;
        }
        #endregion

        #region passenger specific services
        [OperationContract]
        [WebGet()]
        /// <summary>
        /// This is called when a new job is requested by the customer via smart phone
        /// </summary>
        public void RequestJob(string deviceID, string pickup, string destination, double travelDate, int taxiCoy, string customerName, string mobileNo, string telNo)
        {
            // TO DO http://localhost:50133/AjaxPhoneService.svc/RequestJob?deviceID=e3db167e2461dd610b8c1635136c2df522ffefba&pickup=29a Packe Street, Edgeware, Christchurch&destination=143 Peverel Street, Riccarton&travelDate=40447.69140625&taxiShare=False&taxiCoy=1
   
            // Note: if this satement fails check that global::System.Int32 activeJobID is commented out in ActiveJob.CreateActiveJob
            //DateTime.FromOADate(Now)

            ActiveJob job = ActiveJob.CreateActiveJob("", pickup, destination, DateTime.Now, deviceID, mobileNo, telNo, customerName, false);
            _ListItEntities.AddToActiveJobs(job);
            _ListItEntities.SaveChanges();
        }

        [OperationContract]
        [WebGet()]
        /// <summary>
        /// This is used by the phone user to register for the taxi service.  Returns TRUE if registration is successful.
        /// </summary>
        public bool RegisterSmart(string deviceID, string owner, string mobileNo)
        {
            // TO DO http://localhost:50133/AjaxPhoneService.svc/Register?deviceID=e3db167e2461dd610b8c1635136c2df522ffefba&phoneNumber=0211148008&owner=Allan Vergara

            var obj = from customer in _ListItEntities.Customers
                      where customer.DeviceID == deviceID
                      select customer;

            var customerList = obj.ToList<Customer>();

            if (customerList.Count != 0) {
                foreach (var customer in customerList)
                {
                    customer.Owner = owner;
                    customer.PhoneNumber = mobileNo;
                    _ListItEntities.SaveChanges();
                }
            }
            else {
                Customer customer = Customer.CreateCustomer(deviceID, mobileNo, owner);
                _ListItEntities.AddToCustomers(customer);
                _ListItEntities.SaveChanges();
            }

            return true;
        }
        
        [OperationContract]
        [WebGet()]
        /// <summary>
        /// This returns an xml string that contains updates to the phone data.
        /// </summary>
        public string DoUpdate()
        {
            return ""; // xml
        }

        #endregion
    }
}
